package org.yuanqiframework.yuanqi.core.utils.crypto;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;

import java.nio.charset.StandardCharsets;

/**
 * AES加解密工具类
 *
 * @Author 曹波涛
 * @Date 2022/10/31 9:38
 * @Version 1.0
 */
public class AesUtils {

    /**
     * 使用指定密钥加密
     *
     * @param data 待加密的数据
     * @param key  密钥
     * @return 加密后的Base64字符串
     */
    public static String encrypt(String data, String key) {
        return encrypt(data, key.getBytes());
    }

    /**
     * 使用指定密钥加密
     *
     * @param data 待加密的数据
     * @param key  密钥字节数组
     * @return 加密后的Base64字符串
     */
    public static String encrypt(String data, byte[] key) {
        try {
            AES aes = SecureUtil.aes(key);
            return aes.encryptBase64(data, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES加密失败", e);
        }
    }


    /**
     * 使用指定密钥解密
     *
     * @param data 待解密的数据(Base64字符串)
     * @param key  密钥
     * @return 解密后的明文
     */
    public static String decrypt(String data, String key) {
        return decrypt(data, key.getBytes());
    }

    /**
     * 使用指定密钥解密
     *
     * @param data 待解密的数据(Base64字符串)
     * @param key  密钥字节数组
     * @return 解密后的明文
     */
    public static String decrypt(String data, byte[] key) {
        try {
            AES aes = SecureUtil.aes(key);
            return aes.decryptStr(data, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES解密失败", e);
        }
    }

    /**
     * 生成随机AES密钥并返回Base64编码字符串
     *
     * @return Base64编码的AES密钥
     */
    public static String generateKey() {
        return generateKey(null);
    }

    /**
     * 根据指定字符串生成AES密钥并返回Base64编码字符串
     *
     * @param keyStr 用于生成密钥的字符串
     * @return Base64编码的AES密钥
     */
    public static String generateKey(String keyStr) {
        try {
            AES aes;
            if (keyStr == null) {
                aes = SecureUtil.aes();
            } else {
                aes = SecureUtil.aes(keyStr.getBytes());
            }
            return Base64.encode(aes.getSecretKey().getEncoded());
        } catch (Exception e) {
            throw new RuntimeException("生成AES密钥失败", e);
        }
    }
}
